package com.buaa.divinationmaster.algorithm;

import java.util.Calendar;
import java.util.Date;
import java.util.Random;

/**
 * 梅花易数算法
 * 实现梅花易数的起卦和解读逻辑
 */
public class MeihuaAlgorithm {
    
    /**
     * 八卦枚举
     */
    public enum Trigram {
        QIAN("乾", "☰", 1, "天", "健", "刚健、创造、领导"),
        DUI("兑", "☱", 2, "泽", "悦", "喜悦、沟通、收获"),
        LI("离", "☲", 3, "火", "丽", "光明、智慧、美丽"),
        ZHEN("震", "☳", 4, "雷", "动", "震动、奋发、行动"),
        XUN("巽", "☴", 5, "风", "入", "顺从、渐进、深入"),
        KAN("坎", "☵", 6, "水", "陷", "险阻、智慧、流动"),
        GEN("艮", "☶", 7, "山", "止", "停止、静观、稳定"),
        KUN("坤", "☷", 8, "地", "顺", "顺从、包容、厚德");
        
        private final String name;
        private final String symbol;
        private final int number;
        private final String element;
        private final String virtue;
        private final String meaning;
        
        Trigram(String name, String symbol, int number, String element, String virtue, String meaning) {
            this.name = name;
            this.symbol = symbol;
            this.number = number;
            this.element = element;
            this.virtue = virtue;
            this.meaning = meaning;
        }
        
        public String getName() { return name; }
        public String getSymbol() { return symbol; }
        public int getNumber() { return number; }
        public String getElement() { return element; }
        public String getVirtue() { return virtue; }
        public String getMeaning() { return meaning; }
        
        public static Trigram fromNumber(int number) {
            // 将数字转换为1-8范围
            int trigramNum = ((number - 1) % 8) + 1;
            for (Trigram trigram : values()) {
                if (trigram.getNumber() == trigramNum) {
                    return trigram;
                }
            }
            return QIAN; // 默认返回乾卦
        }
    }
    
    /**
     * 起卦方法枚举
     */
    public enum DivinationMethod {
        TIME("时间起卦"),
        MANUAL("手动输入"),  
        RANDOM("随机起卦");
        
        private final String name;
        
        DivinationMethod(String name) {
            this.name = name;
        }
        
        public String getName() { return name; }
    }
    
    /**
     * 梅花易数卦象
     */
    public static class MeihuaHexagram {
        private Trigram upperTrigram;
        private Trigram lowerTrigram;
        private int changingLine; // 动爻位置 (1-6)
        private String hexagramName;
        private String interpretation;
        
        public MeihuaHexagram(Trigram upperTrigram, Trigram lowerTrigram, int changingLine) {
            this.upperTrigram = upperTrigram;
            this.lowerTrigram = lowerTrigram;
            this.changingLine = changingLine;
            this.hexagramName = lowerTrigram.getName() + upperTrigram.getName();
            generateInterpretation();
        }
        
        private void generateInterpretation() {
            StringBuilder sb = new StringBuilder();
            
            sb.append("【").append(hexagramName).append("卦解读】\n\n");
            
            // 卦象结构分析
            sb.append("卦象结构：\n");
            sb.append("上卦：").append(upperTrigram.getName()).append("（").append(upperTrigram.getElement())
              .append("）").append(upperTrigram.getSymbol()).append("\n");
            sb.append("下卦：").append(lowerTrigram.getName()).append("（").append(lowerTrigram.getElement())
              .append("）").append(lowerTrigram.getSymbol()).append("\n");
            sb.append("动爻：第").append(changingLine).append("爻\n\n");
            
            // 卦意分析
            sb.append("【卦意分析】\n");
            sb.append(getHexagramMeaning());
            
            sb.append("\n\n【动爻分析】\n");
            sb.append(getChangingLineMeaning());
            
            sb.append("\n\n【总体指导】\n");
            sb.append(getOverallGuidance());
            
            this.interpretation = sb.toString();
        }
        
        private String getHexagramMeaning() {
            String upper = upperTrigram.getName();
            String lower = lowerTrigram.getName();
            
            // 根据上下卦组合给出基本解释
            if (upper.equals("乾") && lower.equals("乾")) {
                return "乾为天卦，象征天道刚健，万物之始。此卦大吉，主事业兴旺，但需防骄傲自满。";
            } else if (upper.equals("坤") && lower.equals("坤")) {
                return "坤为地卦，象征地道柔顺，包容万物。此卦主安稳，宜守不宜攻，以静制动。";
            } else if (upper.equals("坎") && lower.equals("离")) {
                return "水火既济，象征事情已经达到平衡状态，但需要继续维持，不可松懈。";
            } else if (upper.equals("离") && lower.equals("坎")) {
                return "火水未济，象征事情尚未完成，需要继续努力，不可急于求成。";
            } else {
                // 通用解释
                return String.format("%s在上，%s在下。%s的特质与%s的特质相结合，需要在%s与%s之间寻求平衡。",
                    upperTrigram.getElement(), lowerTrigram.getElement(),
                    upperTrigram.getMeaning(), lowerTrigram.getMeaning(),
                    upperTrigram.getVirtue(), lowerTrigram.getVirtue());
            }
        }
        
        private String getChangingLineMeaning() {
            String[] lineNames = {"初爻", "二爻", "三爻", "四爻", "五爻", "上爻"};
            String lineName = lineNames[changingLine - 1];
            
            String meaning = "";
            switch (changingLine) {
                case 1:
                    meaning = "初爻动，象征事情刚刚开始，基础很重要，需要谨慎行事。";
                    break;
                case 2:
                    meaning = "二爻动，象征内在力量开始显现，需要积蓄力量，不宜急进。";
                    break;
                case 3:
                    meaning = "三爻动，象征处于变化的关键时期，需要果断决策。";
                    break;
                case 4:
                    meaning = "四爻动，象征接近成功，但仍需小心谨慎，不可掉以轻心。";
                    break;
                case 5:
                    meaning = "五爻动，象征处于最佳位置，天时地利人和，是实现目标的好时机。";
                    break;
                case 6:
                    meaning = "上爻动，象征事情已达顶峰，需要考虑退守或转变策略。";
                    break;
            }
            
            return lineName + "：" + meaning;
        }
        
        private String getOverallGuidance() {
            // 根据上下卦的组合给出建议
            String upperElement = upperTrigram.getElement();
            String lowerElement = lowerTrigram.getElement();
            
            if (upperElement.equals("天") || lowerElement.equals("天")) {
                return "天道刚健，建议积极主动，把握机遇，但要注意适度，避免过刚易折。";
            } else if (upperElement.equals("地") || lowerElement.equals("地")) {
                return "地道柔顺，建议以柔克刚，厚德载物，保持谦逊和包容的态度。";
            } else if (upperElement.equals("水") || lowerElement.equals("水")) {
                return "水性智慧，建议灵活应变，以智慧化解困难，如水般找到最佳路径。";
            } else if (upperElement.equals("火") || lowerElement.equals("火")) {
                return "火性光明，建议保持热情和理智，用智慧之光照亮前进的道路。";
            } else {
                return "顺应自然规律，在变化中寻求平衡，既要积极进取，也要懂得适时调整。";
            }
        }
        
        // Getters
        public Trigram getUpperTrigram() { return upperTrigram; }
        public Trigram getLowerTrigram() { return lowerTrigram; }
        public int getChangingLine() { return changingLine; }
        public String getHexagramName() { return hexagramName; }
        public String getInterpretation() { return interpretation; }
    }
    
    /**
     * 梅花易数占卜结果
     */
    public static class MeihuaReading {
        private String question;
        private DivinationMethod method;
        private int upperNumber;
        private int lowerNumber;
        private int changingNumber;
        private MeihuaHexagram hexagram;
        private long timestamp;
        
        public MeihuaReading(String question, DivinationMethod method, 
                           int upperNumber, int lowerNumber, int changingNumber) {
            this.question = question;
            this.method = method;
            this.upperNumber = upperNumber;
            this.lowerNumber = lowerNumber;
            this.changingNumber = changingNumber;
            this.timestamp = System.currentTimeMillis();
            
            // 生成卦象
            Trigram upperTrigram = Trigram.fromNumber(upperNumber);
            Trigram lowerTrigram = Trigram.fromNumber(lowerNumber);
            int changingLine = ((changingNumber - 1) % 6) + 1;
            
            this.hexagram = new MeihuaHexagram(upperTrigram, lowerTrigram, changingLine);
        }
        
        // Getters
        public String getQuestion() { return question; }
        public DivinationMethod getMethod() { return method; }
        public int getUpperNumber() { return upperNumber; }
        public int getLowerNumber() { return lowerNumber; }
        public int getChangingNumber() { return changingNumber; }
        public MeihuaHexagram getHexagram() { return hexagram; }
        public long getTimestamp() { return timestamp; }
    }
    
    /**
     * 时间起卦
     */
    public static MeihuaReading timeBasedDivination(String question) {
        Calendar cal = Calendar.getInstance();
        
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1; // Calendar.MONTH从0开始
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        
        // 计算上卦数
        int upperNumber = (year + month + day) % 8;
        if (upperNumber == 0) upperNumber = 8;
        
        // 计算下卦数
        int lowerNumber = (year + month + day + hour) % 8;
        if (lowerNumber == 0) lowerNumber = 8;
        
        // 计算动爻数
        int changingNumber = (year + month + day + hour + minute) % 6;
        if (changingNumber == 0) changingNumber = 6;
        
        return new MeihuaReading(question, DivinationMethod.TIME, 
                               upperNumber, lowerNumber, changingNumber);
    }
    
    /**
     * 手动输入起卦
     */
    public static MeihuaReading manualDivination(String question, int upperNum, int lowerNum, int changingNum) {
        return new MeihuaReading(question, DivinationMethod.MANUAL, 
                               upperNum, lowerNum, changingNum);
    }
    
    /**
     * 随机起卦
     */
    public static MeihuaReading randomDivination(String question) {
        Random random = new Random();
        
        int upperNumber = random.nextInt(8) + 1;
        int lowerNumber = random.nextInt(8) + 1;
        int changingNumber = random.nextInt(6) + 1;
        
        return new MeihuaReading(question, DivinationMethod.RANDOM, 
                               upperNumber, lowerNumber, changingNumber);
    }
}
